package com.dwy2002.course.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dwy2002.common.Result;
import com.dwy2002.common.exception.EmptyIdException;
import com.dwy2002.common.utils.JwtUtil;
import com.dwy2002.course.mapper.CourseEnrollmentsMapper;
import com.dwy2002.course.mapper.CoursesMapper;
import com.dwy2002.course.service.ICourseEnrollmentService;
import com.dwy2002.pojo.po.courses.CourseEnrollments;
import com.dwy2002.pojo.po.courses.Courses;
import com.dwy2002.pojo.po.users.Users;
import com.dwy2002.pojo.vo.courses.CoursesVO;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.dwy2002.common.Result.success;
import static com.dwy2002.common.utils.Utils.*;
import static com.dwy2002.enums.rabbit.CourseRabbitConstants.*;

/**
 * @author 杜伟毅
 * @version 1.0
 * @since 2025/03/02
 */
@Service
@RequiredArgsConstructor
public class CourseEnrollmentServiceImpl extends ServiceImpl<CourseEnrollmentsMapper, CourseEnrollments> implements ICourseEnrollmentService {
    private final RabbitTemplate rabbitTemplate;
    private final JwtUtil jwtUtil;
    private final CoursesMapper coursesMapper;

    /**
     * 删除报名关系
     *
     * @param courseIds 课程id集合
     * @author 杜伟毅
     * @since 2025/3/2 0002 22:00
     */
    @Override
    public void deleteEnrollment(List<String> courseIds) {
        if (isListEmpty(courseIds)) throw new EmptyIdException("deleteEnrollment");
        LambdaQueryWrapper<CourseEnrollments> lqw = new LambdaQueryWrapper<>();
        lqw.in(CourseEnrollments::getCourseId, courseIds);
        remove(lqw);
    }

    /**
     * 获取课程报名id
     *
     * @param courseId 课程id
     * @return 返回课程报名id
     * @author 杜伟毅
     * @since 2025/3/11 0011 17:12
     */
    @Override
    public String getCourseEnrollmentsId(String courseId) {
        if (isEmptyOrNull(courseId)) throw new EmptyIdException("getCourseEnrollmentsId");

        LambdaQueryWrapper<CourseEnrollments> lqw = new LambdaQueryWrapper<>();
        lqw.eq(CourseEnrollments::getCourseId, courseId);
        String id = getOne(lqw).getId();

        if (isEmptyOrNull(id)) {
            throw new IllegalArgumentException("这个id查询为空" + courseId);
        }
        return id;
    }

    /**
     * 返回用户全部报名课程
     *
     * @author 杜伟毅
     * @since 2025/4/2 0002 17:06
     */
    @Override
    public Result<List<CoursesVO>> getUserEnrollments() {
        String userId = jwtUtil.parseToken(getToken(), Users.class).getId();
        LambdaQueryWrapper<CourseEnrollments> lqw = new LambdaQueryWrapper<>();
        lqw.eq(CourseEnrollments::getUserId, userId);
        List<String> courseIds = list(lqw).stream()
                .map(CourseEnrollments::getCourseId)
                .toList();
        List<Courses> coursesList = coursesMapper.selectByIds(courseIds);
        return success(BeanUtil.copyToList(coursesList, CoursesVO.class));
    }


    //辅助方法-----------------------------------------------------------

    /**
     * 接收课程id，生成并发送报名id，带上订单id
     *
     * @param courseId 课程id
     * @param orderId  订单id
     * @author 杜伟毅
     * @since 2025/3/22 0022 22:06
     */
    @RabbitListener(queues = ENROLLMENT_REQUEST_QUEUE)
    public void handleEnrollmentRequest(String courseId, @Header("orderId") String orderId, Message message) {
        // 生成 enrollmentId
        String enrollmentId = getCourseEnrollmentsId(courseId);

        // 发送响应到 ReplyTo 队列
        rabbitTemplate.convertAndSend(
                ENROLLMENT_RESPONSE_EXCHANGE, // 使用响应专属交换机
                ENROLLMENT_RESPONSE_ROUTING_KEY, // 响应路由键
                enrollmentId,
                respMsg -> {
                    // 携带订单ID，让 Order 模块能关联上下文
                    respMsg.getMessageProperties().setHeader("orderId", orderId);
                    return respMsg;
                }
        );
    }
}
